﻿/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "mainWindow.h"
#include "ui_mainWindow.h"
#pragma execution_character_set("utf-8")
#ifndef QT_NO_SYSTEMTRAYICON
#include <QApplication>
#include <QAction>
#include <QComboBox>
#include <QDesktopServices>
#include <QCoreApplication>
#include <QCloseEvent>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QPushButton>
#include <QSpinBox>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QTableView>
#include <QMessageBox>

#include "notifyWidgetManager.h"
#include "notifyFromChecker.h"
#include "fileSystemWatcher.h"


#define AUTO_RUN "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"

void Window::showMegs(QString tittle, QString msg, QString url, int  durationSec, QString type)
{
    showSystemMessage(tittle, msg, url, durationSec, type);
}

void Window::notify_config_file_update(QString path)
{
#if 0
    // 监视 顶层配置
    mTopConfigFile = mtopConfig->getTopConfigPath();
    mFileSystemWatcher->addWatchPath(mTopConfigFile);
    // 监视 自定义配置
    mCustNotifyFile = mtopConfig->getCustNotifyConfigPath();
    mFileSystemWatcher->addWatchPath(mCustNotifyFile);
    // 监视 行程路径下的配置
    mSchedulePath = mtopConfig->getSchedulePath();
    mFileSystemWatcher->addWatchPath(mSchedulePath);
    if(mTopConfigFile == path)
    {
        mtopConfig->reload();
        mconfigChecker->reload();
        // ....
    }
#endif
    //qDebug() << "Reload" << path;
    reloadConfig();
}

Window::Window(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow)
{
    // 提供监视文件改动的功能
    mFileSystemWatcher =  new FileSystemWatcher();
    // 顶层配置
    mtopConfig = new topConfig;
    mtopConfig->reload();



    // 监视 顶层配置
    mTopConfigFile = mtopConfig->getTopConfigPath();
    mFileSystemWatcher->addWatchPath(mTopConfigFile);
    // 监视 自定义配置
    mCustNotifyFile = mtopConfig->getCustNotifyConfigPath();
    mFileSystemWatcher->addWatchPath(mCustNotifyFile);
    // 监视 行程路径下的配置
    //mSchedulePath = mtopConfig->getSchedulePath();
    //mFileSystemWatcher->addWatchPath(mSchedulePath);

    //m_scheduleInfo = new notifyFromCheckerScheduleHandle;
    m_PeriodicConfig = new notifyFromCheckerPeriodicConfig();

    manager = new NotifyManager(this);

    connect(mFileSystemWatcher, &FileSystemWatcher::NotifyConfigFileUpdated, this, &Window::notify_config_file_update);

    mconfigChecker = new notifyFromChecker();
    //mconfigChecker->InitConfig(mtopConfig->getCustNotifyConfigPath());

#if 1 // 桌面小图标的有关功能
    createTrayIconActions();
    createTrayIcon();
    // 图标的有关交互
    connect(trayIcon, &QSystemTrayIcon::activated, this, &Window::iconActivated);
    setIcon();
    trayIcon->show();
    // Make sure the item can be shown correctly
    //this->Window::setVisible(true);
#endif

    connect(mconfigChecker, &notifyFromChecker::showNotifyWindows, this, &Window::showMegs);
    if(mtopConfig->isEnableRemoteNotify())
    {
        // tcp 连接
        tcpserver = new notifyFromTcpServer;
        connect(tcpserver,      &notifyFromTcpServer::messageIn,            this, &Window::showMegs);
    }


    mconfigChecker->setEnable(true);

#if 1
    //QDialog::setVisible(true);
    QString tittle = tr("开始营业~");
    QString body =  tr("我会定时提醒你的喔。");
    QString url  = tr("");
#else
    QString tittle = tr("一二三四五六七八九十一二三四");
    QString body =   tr("一二三四五六七八九十一二三四");
#endif
    showSystemMessage(tittle, body, url, 5, "info");
    ui->setupUi(this);
}

void Window::setVisible(bool visible)
{
    //enableAction->setEnabled(visible);
    //autoBootAction->setEnabled(!isMaximized());
    //aboutMeAction->setEnabled(isMaximized() || !visible);
    QMainWindow::setVisible(visible);
}

void Window::closeEvent(QCloseEvent *event)
{
#ifdef Q_OS_OSX
    if (!event->spontaneous() || !isVisible()) {
        return;
    }
#endif
    if (trayIcon->isVisible()) {
/*
        QString tittle = tr("Let Me Know");
        QString body =  tr("Running in the Background"
                           "Choose [Quit] in the context menu "
                           "of the system tray entry.");
        int durationSec = 5;

        showSystemMessage(tittle, body, durationSec, QSystemTrayIcon::Information);
*/
        hide();
        event->ignore();
    }
}

void Window::setIcon(void)
{
    QIcon icon("://images/heart.png");
    trayIcon->setIcon(icon);
    setWindowIcon(icon);

    trayIcon->setToolTip(tr("Let me know"));
}

// 关于图标的有关事件
void Window::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
    // 双击、单击时
    case QSystemTrayIcon::Trigger:
    break;case QSystemTrayIcon::DoubleClick:
        setVisible(true);

    break;default:
    break;
    }
}

void Window::showSystemMessage(QString & tittleArg, QString & bodyArg, QString & url, int durationSec, QString type)
{
    NotifyManager::getInstance()->showSystemMessage(tittleArg, bodyArg, url, durationSec, type);
}

void Window::SetMyAppAutoRun(bool isstart)
{
#if 0
    QString url  = tr("");
    int durationSec = 2;

    QString tittle = tr("开心");
    QString body =  tr("设为自启动了哦。");
    showSystemMessage(tittle, body, url, durationSec, "info");
    qDebug() << "Skip From Debug to SetMyAppAutoRun";
#else
    QString url  = tr("");

    int durationSec = 2;

    QSettings *settings = new QSettings(AUTO_RUN, QSettings::NativeFormat);//创建QSetting, 需要添加QSetting头文件

    //获取应用名称
    QString application_name = QApplication::applicationName();

     if(isstart){
         //qDebug() << "set";
         //找到应用的目录
         QString application_path = QApplication::applicationFilePath();
         application_path = application_path.replace(QString('\\'), QString('/'));
         settings->setValue(application_name, application_path);//写入注册表
         QString tittle = tr("开机启动");
         QString body =  tr("设为自启动了哦。");
         showSystemMessage(tittle, body, url, durationSec, "info");
     } else {
         //qDebug() << "remove";
         QString tittle = tr("开机启动");
         QString body =  tr("不再自启动了哦。");
         showSystemMessage(tittle, body, url, durationSec, "error");
         settings->remove(application_name);
     }
#endif
}

void Window::reloadConfig(void)
{
    topConfig::getInstance()->reload();
    if(mconfigChecker->getEnable())
    {
        mconfigChecker->setEnable(false);
        m_PeriodicConfig->reloadPeriodicConfig();
        //m_scheduleInfo->reloadSchedule();
        mconfigChecker->setEnable(true);
    }else
    {
        m_PeriodicConfig->reloadPeriodicConfig();
        //m_scheduleInfo->reloadSchedule();
    }
}

void Window::modifyConfig(void)
{
    qDebug() << "modify";
    QString configPath = "file:///" + topConfig::getInstance()->getCustNotifyConfigPath();
    QDesktopServices::openUrl(QUrl(configPath,QUrl::TolerantMode));
}

int Window::suspendForWhile(bool checked)
{
    QString url  = tr("");
    mconfigChecker->setEnable(checked);
    if(!checked)
    {
        QString tittle = tr("打开提醒");
        QString body =  tr("你怎么把我关掉啦？");

        showSystemMessage(tittle, body, url, 5, "error");
    }else
    {
        QString tittle = tr("关闭提醒");
        QString body =  tr("谢谢你允许我提醒你~");

        showSystemMessage(tittle, body, url, 5, "info");
    }

    return 0;
}

void Window::createTrayIconActions()
{
    enableAction = new QAction(tr("打开提醒"), this);
    enableAction->setCheckable(true);
    enableAction->setChecked(true);
    connect(enableAction, SIGNAL(triggered(bool)), this, SLOT(suspendForWhile(bool)));

    autoBootAction = new QAction(tr("开机启动"), this);
    autoBootAction->setCheckable(true);
    connect(autoBootAction, SIGNAL(triggered(bool)), this, SLOT(SetMyAppAutoRun(bool)));

    // 准备读取注册表，NativeFormat在windows下就是系统注册表
    QSettings *settings = new QSettings(AUTO_RUN, QSettings::NativeFormat);
    //获取应用名称
    QString application_name = QApplication::applicationName();
    //找到应用的目录
    QString application_path = QApplication::applicationFilePath();
    application_path = application_path.replace(QString('\\'), QString('/'));
    QString result = settings->value(application_name).toString();

    autoBootAction->setChecked(!result.isEmpty());

    reloadConfigAction = new QAction(tr("刷新提醒"), this);
    connect(reloadConfigAction, SIGNAL(triggered(bool)), this, SLOT(reloadConfig(void)));

    modifyConfigAction = new QAction(tr("修改提醒"), this);
    connect(modifyConfigAction, SIGNAL(triggered(bool)), this, SLOT(modifyConfig(void)));

    aboutMeAction = new QAction(tr("关于"), this);
    connect(aboutMeAction, &QAction::triggered, this, &QWidget::showNormal);

    quitAction = new QAction(tr("退出"), this);
    connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
}

void Window::createTrayIcon()
{
    trayIconMenu = new QMenu(this);
    trayIconMenu->addAction(enableAction);
    trayIconMenu->addAction(autoBootAction);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(reloadConfigAction);
    trayIconMenu->addAction(modifyConfigAction);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(aboutMeAction);
    trayIconMenu->addAction(quitAction);


    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayIconMenu);
}

#endif

void Window::on_DebugTabPushButtonDemo_released()
{
    QString url  = tr("https://gitee.com/schips"); // OK
    //QString url  = tr("D:/"); //OK
    //QString url  = tr("D:/tmp.xlsx"); //OK
    //QString url  = tr("python --version"); // OK
    //QString url  = tr("python --version"); // OK
    QString tittle = tr("一二三四五六七八九十一二三四");
    QString body =   tr("一二三四五六七八九十一二三四");
    showSystemMessage(tittle, body, url, 5, "info");
}



void Window::on_DebugTabPushButtonEditTop_released()
{
    runURl( topConfig::getInstance()->getTopConfigPath());
}

void Window::on_DebugTabPushButtonEditCustomINI_released()
{
    runURl( topConfig::getInstance()->getCustNotifyConfigPath());
}

void Window::on_DebugTabPushButtonEditCSS_released()
{
    runURl( topConfig::getInstance()->getNotifyCSSPath());
}

